InĀ [1]:
# Install cartopy ,un comment the below
# !apt-get install -y python3-cartopy
# !pip install cartopy
InĀ [2]:
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from IPython.display import HTML
import cartopy.crs as ccrs
import cartopy.feature as cfeature
# Dataset: Flyway paths with coordinates
# Reference: https://datazone.birdlife.org/sowb/spotflyway
flyways = {
"Pacific Flyway": [
[-145.500, 60.333], [-132.383, 56.533], [-123.150, 49.050], [-79.550, 8.950], [-79.850, -1.400], [-70.950, -17.400],
],
"Central Flyway": [
[-112.500, 53.400],[-106.580,50.450],[-98.277,50.185],[-89.783,15.183],[-85.083,11.033],[-59.933,-30.583],
],
"Atlantic Flyway": [
[-72.500, 67.500], [-64.633, 45.800], [-85.350, 42.316], [-52.800, 5.000], [-37.000, -4.000], [-66.000, -54.000],
],
"East Atlantic Flyway": [
[32.000, 60.000], [6.500, 53.500], [-5.353, 36.140], [-16.000, 20.933], [-16.000, 16.000], [-15.000, 11.000],
],
"Black Sea-Mediterranean Flyway": [
[94.500, 54.500], [29.000, 41.200], [35.400, 32.500], [35.000, 29.500], [-7.500, 12.000], [31.000, 6.000],
],
"East Asia-East Africa": [
[68.000, 51.300], [49.500, 37.466], [43.200, 13.000], [32.500, 0.350], [22.000, -19.000], [31.100, -29.650],
],
"East AsiaāAustralasia Flyway": [
[156.301, 58.258], [124.000, 40.000], [120.250, 23.200], [114.000, 22.500], [138.500, -19.500], [121.000, -19.000],
],
"Central Asian Flyway": [
[65.944, 56.334], [80.050, 29.400], [77.566, 27.150], [70.200, 23.500], [75.516, 16.984],[79.500, 10.400],
]
}
# Plot setup
fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}, figsize=(12, 6))
ax.set_global()
ax.coastlines()
ax.add_feature(cfeature.BORDERS, linestyle=':')
ax.add_feature(cfeature.LAND, facecolor='lightgray')
ax.add_feature(cfeature.OCEAN, facecolor='lightblue')
fig.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=None, hspace=None)
# Colors for each flyway
colors = ["red", "blue", "green", "purple", "orange", "cyan", "brown", "yellow"]
# Prepare line objects and flyway data
lines = []
flyway_data = []
for i, (flyway, points) in enumerate(flyways.items()):
lons, lats = zip(*points)
line, = ax.plot([], [], label=flyway, color=colors[i % len(colors)], transform=ccrs.Geodetic(), linewidth=2)
lines.append(line)
flyway_data.append((lons, lats))
# Function to update animation
def update(frame):
for i, line in enumerate(lines):
lons, lats = flyway_data[i]
if frame < len(lons): # North-to-south movement
line.set_data(lons[:frame + 1], lats[:frame + 1])
else: # South-to-north movement
reverse_frame = frame - len(lons)
line.set_data(lons[:len(lons) - reverse_frame - 1], lats[:len(lats) - reverse_frame - 1])
return lines
# Total frames: twice the length of the longest flyway path for back-and-forth motion
max_length = max(len(points) for points in flyways.values())
total_frames = 2 * max_length
# Create animation
ani = animation.FuncAnimation(fig, update, frames=total_frames, interval=200, blit=True)
# Display animation
HTML(ani.to_jshtml())
Out[2]:
InĀ [3]:
writergif = animation.PillowWriter(fps=5)
ani.save('birds-flyway.gif',writer=writergif)